package com.spc.car.common.utils.text.gson;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;

public final class GsonUtils {
    private static Gson gson = (new GsonBuilder()).serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss").registerTypeAdapter(Date.class, new DateTypeEmptyToNullAdapter()).registerTypeAdapter(BigDecimal.class, new BigDecimalTypeEmptyToZeroAdapter()).create();

    public static GsonBuilder getGsonBuilder() {
        return (new GsonBuilder()).serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss").registerTypeAdapter(Date.class, new DateTypeEmptyToNullAdapter()).registerTypeAdapter(BigDecimal.class, new BigDecimalTypeEmptyToZeroAdapter());
    }

    public static <T> T fromJsonToClass(String json, Class<T> mainClass, Class subClass) {
        if (null == subClass) {
            return gson.fromJson(json, mainClass);
        } else {
            Type objectType = type(mainClass, subClass);
            return gson.fromJson(json, objectType);
        }
    }

    public static <T> T fromJsonForType(String json, Type type) {
        return gson.fromJson(json, type);
    }

    public static <T> T fromJsonToClass(String json, Class<T> clz) {
        return gson.fromJson(json, clz);
    }

    public static String toJson(Object obj) {
        return gson.toJson(obj);
    }

    public static String toJsonIgnoreFld(Object obj) {
        return toJson(obj, (List)null, true);
    }

    public static String toJsonIncludeFld(Object obj, List<String> fldNameList) {
        return toJson(obj, fldNameList, true);
    }

    public static String toJsonExcludeFld(Object obj, List<String> fldNameList) {
        return toJson(obj, fldNameList, false);
    }

    public static String toJson(Object obj, List<String> fldNameList, boolean inclusive) {
        return CollectionUtils.isNotEmpty(fldNameList) ? getGsonBuilder().addSerializationExclusionStrategy(new IgnoreFieldStrategy(fldNameList, inclusive)).create().toJson(obj) : getGsonBuilder().create().toJson(obj);
    }

    public static String toJson(Object obj, boolean prettyPrinting) {
        return prettyPrinting ? getGsonBuilder().setPrettyPrinting().create().toJson(obj) : gson.toJson(obj);
    }

    public static String toJsonFromClass(Object obj, Class mainClass, Class subClass) {
        if (null == subClass) {
            return gson.toJson(obj, mainClass);
        } else {
            Type objectType = type(mainClass, subClass);
            return gson.toJson(obj, objectType);
        }
    }

    public static Map<String, Object> fromJsonToMap(String json) {
        Gson gson = (new GsonBuilder()).registerTypeAdapter((new TypeToken<Map<String, Object>>() {
        }).getType(), new MapTypeAdapter()).create();
        return (Map)gson.fromJson(json, (new TypeToken<Map<String, Object>>() {
        }).getType());
    }

    public static ParameterizedType type(final Class raw, final Type... args) {
        return new ParameterizedType() {
            public Type getRawType() {
                return raw;
            }

            public Type[] getActualTypeArguments() {
                return args;
            }

            public Type getOwnerType() {
                return null;
            }
        };
    }

    private GsonUtils() {
        throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
    }
}
